##
#   Project: gmediacatalog - Catalog your media to find them later
#    Author: Fabio Castelli <muflone@vbsimple.net>
# Copyright: 2010 Fabio Castelli
#   License: GPL-2+
#  This program is free software; you can redistribute it and/or modify it
#  under the terms of the GNU General Public License as published by the Free
#  Software Foundation; either version 2 of the License, or (at your option)
#  any later version.
# 
#  This program is distributed in the hope that it will be useful, but WITHOUT
#  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
#  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
#  more details.
# 
# On Debian GNU/Linux systems, the full text of the GNU General Public License
# can be found in the file /usr/share/common-licenses/GPL-2.
##

PLUGIN_NAME = 'ZIP'
PLUGIN_VERSION = '0.1'
PLUGIN_DESCRIPTION = 'ZIP extraction filter'
PLUGIN_AUTHOR = 'Fabio Castelli'

import zipfile
import time

from constants import *
from plugins import GMediaCatalogPlugin, register_plugin

class GMediaCatalogPlugin_ZIP(GMediaCatalogPlugin):
  def __init__(self, name, version, description, author):
    "Module initialization"
    GMediaCatalogPlugin.__init__(self, name, version, description, author)
    self.logger('__init__("%s", "%s", "%s", "%s")' % (
      PLUGIN_NAME, PLUGIN_VERSION, PLUGIN_AUTHOR, PLUGIN_DESCRIPTION))
    self.connection = None
    self.active = False

  def on_uiready(self, ui, connection):
    self.connection = connection

  def on_terminate(self):
    self.connection = None

  def on_new_file(self, volume_id, folder_id, child, info, category_id):
    if child.is_native() and info.get_content_type() in (
      'application/zip'                               # .zip
    ):
      try:
        zip = zipfile.ZipFile(child.get_path(), 'r')
        # Add a new path for the tarfile
        tar_id = self.connection.add_path(
          volume_id, 
          child.get_uri().replace('%20', ' '),
          info.get_icon().get_names()
        )
        paths = {}
        ublanks = unicode('')
        # Cycle tar content
        for info in zip.infolist():
          name = info.filename
          # Strip initial /
          if name.startswith('/'):
            name = name[1:]
          uri = '%s/%s' % (child.get_uri().replace('%20', ' '), name)
          is_dir = name.endswith('/')
          if is_dir:
            name = name[:-1]
    
          # Item is a directory?
          if '/' in name:
            path, basename = name.rsplit('/', 1)
          else:
            path = ''
            basename = name
    
          if is_dir:
            # Add new directory and add it to paths list
            paths[name] = self.connection.add_path(volume_id, uri, '')

          mtime = time.mktime(info.date_time + (0, 0, 0))

          if path and not paths.has_key(path):
            # Add new directory from the file path to paths list
            paths[path] = self.connection.add_path(volume_id,
            '%s/%s' % (child.get_uri().replace('%20', ' '), path), '')
            # Add file
            self.connection.add_file(
              volume_id,                                  # Volume ID FK
              tar_id,                                     # Path ID FK
              unicode(path),                              # File name
              info.file_size,                             # Size
              ITEM_PATH,                                  # File Type
              ublanks,                                    # Content type
              ublanks,                                    # Icons list
              mtime,                                      # Modification time
              mtime,                                      # Access time
              mtime,                                      # Changed time
              ublanks,                                    # User owner
              ublanks,                                    # User group
              040777,                                     # Mode
              ublanks,                                    # Target
              0,                                          # Flags (hidden)
              ublanks,                                    # Description
              category_id,                                # Category ID FK
              0                                           # Extra info
            )

          # Add file
          self.connection.add_file(
            volume_id,                                  # Volume ID FK
            path and paths[path] or tar_id,             # Path ID FK
            unicode(basename),                          # File name
            info.file_size,                             # Size
            is_dir and ITEM_PATH or ITEM_FILE,          # File Type
            ublanks,                                    # Content type
            ublanks,                                    # Icons list
            mtime,                                      # Modification time
            mtime,                                      # Access time
            mtime,                                      # Changed time
            ublanks,                                    # User owner
            ublanks,                                    # User group
            0777 | (is_dir and 040000 or 0),            # Mode
            ublanks,                                    # Target
            0,                                          # Flags (hidden)
            info.comment,                               # Description
            category_id,                                # Category ID FK
            0                                           # Extra info
          )
    
        zip.close()
      except zipfile.BadZipfile:
        self.logger('bad zip file %s' % child.get_path())
      paths = None

plugin = GMediaCatalogPlugin_ZIP(
  PLUGIN_NAME, PLUGIN_VERSION, PLUGIN_DESCRIPTION, 
  PLUGIN_AUTHOR)
register_plugin(PLUGIN_NAME, plugin)
